# LeetCode 24、两两交换链表中的节点
# 一、题目描述
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 1:
输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]
提示:
- 链表中节点的数目在范围 [0, 100] 内
- 0 <= Node.val <= 100
# 二、题目解析
# 三、参考代码
# 1、Java 代码
// 登录 AlgoMooc 官网获取更多算法图解
// https://www.algomooc.com
// 作者:程序员吴师兄
// 代码有看不懂的地方一定要私聊咨询吴师兄呀
// 两两交换链表中的节点(LeetCode 24): https://leetcode.cn/problems/swap-nodes-in-pairs/
class Solution {
public ListNode swapPairs(ListNode head) {
// 寻找递归终止条件
// 1、head 指向的结点为 null
// 2、head 指向的结点的下一个结点为 null
// 在这两种情况下,一个节点或者空节点无论怎么交换操作,都是原来的 head
if( head == null || head.next == null) {
return head;
}
// 不断的通过递归调用,直到无法递归下去,递归的最小粒度是在最后一个节点或者最后两个节点
ListNode subHead = swapPairs(head.next.next);
// 对于 head 这个节点来说,它是和它相邻的右边这个节点进行交换操作
// 所以先要保存这个节点,并且经过上述递归终止条件的判断,head.next 是必然存在的
ListNode headNext = head.next;
// head 原来是指向 headNext
// 交换之后
// headNext 指向 head
headNext.next = head;
// headNext 原来是指向 subHead
// 现在需要让 head 指向 subHead
head.next = subHead;
// 交换之后,原来的第二位的那个节点 headNext 变成了第一位
// 把它返回就行
return headNext;
}
}
# **2、C++ **代码
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
// 寻找递归终止条件
// 1、head 指向的结点为 null
// 2、head 指向的结点的下一个结点为 null
// 在这两种情况下,一个节点或者空节点无论怎么交换操作,都是原来的 head
if( head == NULL || head->next == NULL) {
return head;
}
// 不断的通过递归调用,直到无法递归下去,递归的最小粒度是在最后一个节点或者最后两个节点
ListNode *subHead = swapPairs(head->next->next);
// 对于 head 这个节点来说,它是和它相邻的右边这个节点进行交换操作
// 所以先要保存这个节点,并且经过上述递归终止条件的判断,head.next 是必然存在的
ListNode *headNext = head->next;
// head 原来是指向 headNext
// 交换之后
// headNext 指向 head
headNext->next = head;
// headNext 原来是指向 subHead
// 现在需要让 head 指向 subHead
head->next = subHead;
// 交换之后,原来的第二位的那个节点 headNext 变成了第一位
// 把它返回就行
return headNext;
}
};
# 3、Python 代码
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
# 寻找递归终止条件
# 1、head 指向的结点为 null
# 2、head 指向的结点的下一个结点为 null
# 在这两种情况下,一个节点或者空节点无论怎么交换操作,都是原来的 head
if head == None or head.next == None :
return head
# 不断的通过递归调用,直到无法递归下去,递归的最小粒度是在最后一个节点或者最后两个节点
subHead = self.swapPairs(head.next.next)
# 对于 head 这个节点来说,它是和它相邻的右边这个节点进行交换操作
# 所以先要保存这个节点,并且经过上述递归终止条件的判断,head.next 是必然存在的
headNext = head.next
# head 原来是指向 headNext
# 交换之后
# headNext 指向 head
headNext.next = head
# headNext 原来是指向 subHead
# 现在需要让 head 指向 subHead
head.next = subHead
# 交换之后,原来的第二位的那个节点 headNext 变成了第一位
# 把它返回就行
return headNext
# 复杂度分析
时间复杂度:O(n),其中 n 是链表的节点数量。需要对每个节点进行更新指针的操作。
空间复杂度:O(n),其中 n 是链表的节点数量。空间复杂度主要取决于递归调用的栈空间。